package com.raos.zkconfig.handwritten.beanpostprocessor;

import com.raos.zkconfig.handwritten.refresh.FieldDetail;
import com.raos.zkconfig.handwritten.refresh.RaosRefreshScope;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 手写 ZK 配置中心之 zk配置中心属性变化后解析刷新后置处理器
 *
 * @author raos
 * @emil 991207823@qq.com
 * @date 2022/9/5 22:56
 */
@Component
public class ParseRaosRefreshScopeBeanPostProcessor implements BeanPostProcessor {

    private Map<String, FieldDetail> fieldDetailMap = new HashMap<>();

    public Map<String, FieldDetail> getFieldDetailMap() {
        return fieldDetailMap;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clazz = bean.getClass();
        if (clazz.isAnnotationPresent(RaosRefreshScope.class)) {
            System.out.println(clazz);   // class com.jack.controller.ProductController
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Value.class)) {
                    Value value = field.getAnnotation(Value.class);
                    String val = value.value();  // 获取到了对应的value值 ${id} ---> id @Value("${id}")
                    val = val.substring(2, val.indexOf("}"));   // 截取配置属性名，例如id
                    /**
                     * val: id
                     * val: product
                     * val: price
                     */
                    System.out.println("val: " + val);
                    // 保存 val 对应的Field和Field所在的clazz
                    /**
                     * id, FieldDetail
                     * product,FieldDetail
                     * price,FieldDetail
                     */
                    this.fieldDetailMap.put(val, new FieldDetail(field, bean));
                }
            }
            System.out.println("属性赋值...");
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

}